package com.wufeng.mycode;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * volatile 关键字
 * 1、可见性
 * 2、非原子性
 * 3、防止指令重排
 *
 * 解决非原子性
 * 1、synchronized （大材小用）
 * 2、atomic（原子类） AtomicInteger
 */
public class VolatileDemo {
    volatile int num = 0;

    public void addTo60() {
        num = 60;
    }

    public synchronized void addPlusPlus() {
        num ++;
    }

    AtomicInteger atomicInteger = new AtomicInteger();

    public void myAddPlus(){
        atomicInteger.getAndIncrement();
    }

    public static void main(String[] args) {
        VolatileDemo demo = new VolatileDemo();
        for (int i = 0; i < 20; i++) {
            new Thread(()->{
                System.out.println(Thread.currentThread().getName() + "\t running");
                for (int j = 0; j < 1000; j++) {
                    demo.addPlusPlus();
                    demo.myAddPlus();
                }
            },String.valueOf(i)).start();
        }
        /**
         * 当前线程数大于 2时，证明以上启动的线程都执行完毕
         * 还存在的线程 main线程和GC线程（守护线程）
         */
        while(Thread.activeCount() > 2){
            Thread.yield();
        }

        System.out.println("finally num is " + demo.num);
        System.out.println("finally atomicInteger is " + demo.atomicInteger);
    }

    /**
     * 验证了volatile 关键字的可见性
     * 添加volatile修饰
     *
     * @param args
     */
    public static void setSaw(String[] args) {
        VolatileDemo demo = new VolatileDemo();
        new Thread(() -> {
            System.out.println(Thread.currentThread().getName() + "\t come in");
            try {
                TimeUnit.SECONDS.sleep(4);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            demo.addTo60();
        }, "AAAA").start();
        while (demo.num == 0) {
        }
        System.out.println(Thread.currentThread().getName() + "\t finally num is " + demo.num);
    }


}
